/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MDS;

import CollaborativeFilttering.Estruturas.MusicSet;
import CollaborativeFilttering.FiltragemColaborativa;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import mdsj.MDSJ;

/**
 *
 * @author Pedro
 */
public class MDS
{
    double [][] matrizAdjacencia;
    double [][] coordenadas;

    FiltragemColaborativa filtragem;

    public MDS(FiltragemColaborativa filtragem)
    {
       this.filtragem = filtragem;
      
    }

    private void ExecutarMDS()
    {
       matrizAdjacencia = filtragem.retornaMatrizAdjacencia();
       coordenadas = MDSJ.classicalScaling(matrizAdjacencia, CalcularCoordenadas());
    }

    public ArrayList<MusicSet> getRecomendadas()
    {
       ExecutarMDS();
       ArrayList<MusicSet> mapa2 = new ArrayList<MusicSet>();
       ArrayList<MusicSet> topSongs = filtragem.getTopSong(10);
       ArrayList<MusicSet> topSimilar = new ArrayList<MusicSet>();
       
       topSimilar.addAll(filtragem.musicasNaRede);
        
       int i = 0;
       
       for(MusicSet music: topSongs)
       {
             int requested = filtragem.musicasNaRede.indexOf(music);
             double[] cordenadas = getCoordinates(requested, CalcularCoordenadas(), matrizAdjacencia);

                int count = 0;
                for(int o = 0; o < coordenadas[0].length; o++)
                {
                    //System.out.println(sumCordinates(getCoordinates(o, 3, resultado), cordenadas));
                    double euclidean = sumCordinates(getCoordinates(o, CalcularCoordenadas(), matrizAdjacencia), cordenadas);
                    MusicSet similar = topSimilar.get(o);
                    similar.setDistancia(similar.getDistancia() + euclidean);
                }
        }
       
       for(MusicSet m: topSimilar)
       {
          m.setDistancia(m.getDistancia() / 20);
       }
       
       ordenaMusicas(topSimilar);
       
       for(int j = 0; j < 20 && j < topSimilar.size(); j++)
           mapa2.add(topSimilar.get(j));
       
       return mapa2;
    }

    private int CalcularCoordenadas()
    {
       return 3;
    }

    public static double[] getCoordinates(int index, int dim, double[][]matrix)
    {
        double[] retorno = new double[dim];

        for(int j = 0; j < dim; j++)
        {
            retorno[j] = matrix[j][index];
        }

        return retorno;
    }

    public static double sumCordinates(double[] cordinatesAlpha, double[] cordinatesBeta)
    {
        double retorno = 0;

        for(int i = 0; i < cordinatesAlpha.length; i++)
        {
            retorno += Math.pow(cordinatesAlpha[i] - cordinatesBeta[i], 2);
        }
        return retorno;
    }
    
     public void ordenaMusicas(ArrayList<MusicSet> music)
    {
       ArrayList lista = (ArrayList)music;
       Collections.sort(lista,new Comparator(){
            public int compare(Object o1, Object o2) {
                MusicSet m1 = (MusicSet)o1;
                MusicSet m2 = (MusicSet)o2;
                return (m1.getDistancia() < m2.getDistancia() ? 1 : (m1.getDistancia() > m2.getDistancia() ? -1 : 0));
            }
        });
    }    
}
